package com.hk.Mgr.web.controller.common;

import com.hk.Mgr.web.message.StatusCode;
import com.hk.Mgr.web.message.kyc.AnswerPhoneReq;
import com.hk.Mgr.web.message.kyc.KycRes;
import com.hk.Mgr.web.message.kyc.QuestionPhoneRes;
import com.hk.Mgr.web.message.kyc.QuestionPhoneResBase;
import com.hk.base.BaseCtrl;
import com.hk.base.ResponseBase;
import com.hk.commons.*;
import com.hk.commons.enm.KYCEnum;
import com.hk.commons.entity.Answer;
import com.hk.commons.entity.Question;
import com.hk.commons.entity.sys.SysUser;
import com.hk.context.RiskEvaluationContext;
import com.hk.service.kyc.IQuestion;
import com.hk.service.sys.IAnswer;
import com.hk.service.sys.ISysUser;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

/**
 * @author psx 职务实现类
 */
@Controller
@RequestMapping(value = BaseCtrl.CommonRootPath + "/ComKycCtrl")
public class ComKycCtrl extends BaseCtrl {
	
	//设置保存答案的时间为一个小时，一个小时之后将会被自动摧毁
	public static final int TIME_OUT_SECONDS = 3600;
	
	private Logger logger = LoggerFactory.getLogger(ComKycCtrl.class);

	@Autowired
	private IQuestion questionService;

	@Autowired
	private IAnswer answerService;

	@Autowired
	private ISysUser sysUserService;

    @Autowired
    private RiskEvaluationContext riskEvaluationContext;

    /**
     * 获取KYC问题，不需要输入参数，直接把所有问题返回
     *
     * @return
     */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @ResponseBody
    public QuestionPhoneResBase<List<QuestionPhoneRes>> list(Long groupId) {
        QuestionPhoneResBase<List<QuestionPhoneRes>> resp = new QuestionPhoneResBase<>();

        List<QuestionPhoneRes> questionPhoneReslist = riskEvaluationContext.listQuestions(groupId);

        resp.setQuestionInfo(questionPhoneReslist);
        return resp;
	}

	/**
	 * 获取KYC问题，不需要输入参数，直接把所有问题返回
	 * @return
	 */
	@RequestMapping(value = "/listAll", method = RequestMethod.GET)
	@ResponseBody
	public QuestionPhoneResBase<List<QuestionPhoneRes>> listAll() {
		 

		QuestionPhoneResBase<List<QuestionPhoneRes>> resp = new QuestionPhoneResBase<List<QuestionPhoneRes>>();

		List<QuestionPhoneRes> questionPhoneReslist = new ArrayList<>();

		HqlFilter hqlFilter = new HqlFilter();

		List<Question> list = questionService.findByFilter(hqlFilter);

		int seqNum = 0;
		for (Question qu : list) {
			seqNum++;
			QuestionPhoneRes quPhoneRes = new QuestionPhoneRes();
			// 设置题目
			quPhoneRes.setQuestion(qu.getQuestion());
			// 设置答案
			String[] selectionArray = null;
			String selectionStr = qu.getAnswer();
			selectionArray = selectionStr.split(",");
			quPhoneRes.setSelection(selectionArray);
			// 设置顺序
			quPhoneRes.setSeqNum(String.valueOf(seqNum));
			questionPhoneReslist.add(quPhoneRes);
		}
		resp.setQuestionInfo(questionPhoneReslist);
		return resp;
	}

	
	/**
	 * 保存用户答题的答案，一次回答一个题
	 *
	 */
	@RequestMapping(value = "/answer", method = RequestMethod.POST)
	@ResponseBody
	public void answer(@RequestBody AnswerPhoneReq req) {

		String questionId = req.getQuestionId();
		String selection = req.getSelection();
		String mobileId = req.getMobileId();
		 
		// 设置用户已经答题的长度
		Long answerLength =   Long.valueOf(0);

		logger.info("common/ComKycCtrl/answer 输入参数为：mobileId = " + mobileId
				+ " questionId = " + questionId + " selection = " + selection);

		Answer an = new Answer();
		// 如果答题不存在
		if (!RedisCilent.existsKey(CacheConstants.MobileId + mobileId)) {
			an.setMobileId(mobileId);
			an.setQuestionArray(questionId);
			an.setAnswerArray(selection);
			answerLength = (long) 1;
		} else {
			String anStr = RedisCilent
					.getString(CacheConstants.MobileId + mobileId);
			an = JsonUtils.toBean(anStr, Answer.class);

			// 获取问题数组
			String questionStr = an.getQuestionArray();
			String[] questionArray = questionStr.split(",");

			// 获取选项数组
			String answerStr = an.getAnswerArray();
			String[] selectionArray = answerStr.split(",");

			// 设置指针，判断题目是否已经保存
			Boolean in = false;

			// 如果问题已经回答
			for (int i = 0; i < questionArray.length; i++) {
				if (questionId.equals(questionArray[i])) {
					selectionArray[i] = selection;
					in = true;
					answerLength = (long) questionArray.length;
					// 跳出循环
					i = questionArray.length + 1;
					an.setQuestionArray(StringUtils.join(questionArray, ","));
					an.setAnswerArray(StringUtils.join(selectionArray, ","));
				}
			}

			// 如果问题还没有回答, 则直接拼接
			if (in == false) {
				an.setQuestionArray(questionStr + "," + questionId);
				an.setAnswerArray(answerStr + "," + selection);
				answerLength = (long) (questionArray.length + 1);
			}
		}

		HqlFilter hqlFilter = new HqlFilter();
		Long questionAccount = questionService.countByFilter(hqlFilter);
		logger.info("已经回答的问题数为 = " + answerLength + " questionAccount = "
				+ questionAccount);

		// 保存用户答题记录到缓存中
		RedisCilent.setString(CacheConstants.MobileId + mobileId,
				JsonUtils.toJson(an),TIME_OUT_SECONDS);
		// 如果问题长度和答案相同，则更改用户信息
		if (answerLength.equals(questionAccount)) {
			getRisk(an);
		}

	}

	/**
	 * 计算用户的风险等级
	 *
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/getRiskLevel", method = RequestMethod.POST)
	public  KycRes getRiskLevel(@RequestBody AnswerPhoneReq req) {
		logger.info("common/ComKycCtrl/getRiskLevel info：mobileId ={}, userId={}", req.getMobileId(), req.getUserId());
		ResponseBase<KycRes> resp = new ResponseBase<KycRes>();

		KycRes result  = new KycRes();

		// 获取mobileId
		String mobileId = req.getMobileId();

		// 获取 userId
		String userIdStr = req.getUserId();

		if(StringHelper.isNotEmpty(userIdStr)){

			Long userId = Long .valueOf(userIdStr);

			SysUser user = sysUserService.findById( userId);
			if(user != null){
				mobileId = user.getMobileId();
			}
		}



		// 获取用户答题记录
		Answer an = answerService.getByMobileId(mobileId);

		// 如果用户答题为空，则返回0， 不为空则计算
		if (an != null && StringUtils.isNotEmpty(an.getScore())) {
			result.setRiskLevel(an.getScore());
			result.setDesc(an.getScoreDesc());
			result.setLongDesc(an.getScoreLongDesc());
		} else {
			result.setDesc("KYC尚未完成");
		}

		logger.info("mobileId = " + mobileId + "   Kyc 总得分为" + result.getDesc());

		return result;
	}

	/**
	 * 手机端传用户答题信息，后台计算风险等级，并且保存结果
	 * @param
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/saveRiskLevel", method = RequestMethod.POST)
	public ResponseBase<KycRes> saveRiskLevel(@RequestBody AnswerPhoneReq req) {
		ResponseBase<KycRes> resp = new ResponseBase<KycRes>();
		
		
		logger.info("common/ComKycCtrl/saveRiskLevel info:mobileId = "
				+ req.getMobileId());
		// 获取用户id
		String mobileId = req.getMobileId();

		// 获取用户答题记录
		Answer an = new Answer();
		
		an.setQuestionArray(req.getQuestionArray());
		an.setAnswerArray(req.getSelectionArray());
		an.setMobileId(req.getMobileId());
		
		KycRes kyc = getRisk(an);
		
		resp.setResult(kyc);
		resp.setResultCode(StatusCode.SUCCESS.key());
		
		logger.info("mobileId = " + mobileId + "   Kyc total Score :" + kyc.getDesc());

		return resp;
	}


	/**
	 * 手机端传用户答题信息，后台计算风险等级，并且保存结果
	 * @param
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/creatKycContract", method = RequestMethod.GET)
	public ResponseBase<KycRes> creatKycContract() {
		ResponseBase<KycRes> resp = new ResponseBase<>();
		HqlFilter hqlFilter = new HqlFilter();
		hqlFilter.addSql(" where 1=1 and (kycHTMLUrl is null or kycPdfUrl is null)");
		List<Answer> answerList = answerService.findByFilter(hqlFilter);
		for(Answer answer : answerList){
			try{
				//异步生成合同链接
				if(StringHelper.isEmpty(answer.getKycHTMLUrl()) || StringHelper.isEmpty(answer.getKycPDFUrl())){
					answerService.updKycUrl(answer.getUserId());
				}
			}catch (Exception e){
				logger.error("create pdf kyc url failed");
			}
		}

		resp.setResultCode(StatusCode.SUCCESS.key());
		return resp;
	}


	/**
	 * 手机端传用户答题信息，后台计算风险等级，并且保存结果
	 * @param
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/creatKycContractByUserId", method = RequestMethod.GET)
	public ResponseBase<KycRes> creatKycContractByUserId(@RequestParam Long  userId) {
		ResponseBase<KycRes> resp = new ResponseBase<>();
		Answer answer = answerService.getByUserId(userId);
		try{
			//异步生成合同链接
			if(StringHelper.isEmpty(answer.getKycHTMLUrl()) || StringHelper.isEmpty(answer.getKycPDFUrl())){
				answerService.updKycUrl(answer.getUserId());
			}
		}catch (Exception e){
			logger.error("create pdf kyc url failed");
		}
		resp.setResultCode(StatusCode.SUCCESS.key());
		return resp;
	}

	
	
	/**
	 * 获取用户的风险测评信息, 并且保存
	 * 
	 * @param
	 * @param
	 * @return KycRes 封装后的Kyc
	 */
	private KycRes getRisk(Answer an) {
		logger.info("getRisk function mobileId = " + an.getMobileId()
				+ " answer = " + an.getAnswerArray());
		KycRes resp = new KycRes();

		Integer riskScore = 0;
		String[] questionArray = null;
		String[] selectionArray = null;

		// 获取题目
		questionArray = an.getQuestionArray().split(",");
		// 获取用户选项
		selectionArray = an.getAnswerArray().split(",");

		for (int i = 0; i < questionArray.length; i++) {
			logger.info("question id = " + questionArray[i] + " selection = "
					+ selectionArray[i]);
			riskScore += getQuestionValue(questionArray[i], selectionArray[i]);
		}

		if (riskScore <= 10) {
			resp.setRiskLevel(KYCEnum.KYCRiskLevel_A1.getCode());
			resp.setDesc(KYCEnum.KYCRiskLevel_A1.getDesc());
			resp.setLongDesc(KYCEnum.KYCRiskLevel_A1.getLongDesc());
		} else if (11 <= riskScore && riskScore <= 19) {
			resp.setRiskLevel(KYCEnum.KYCRiskLevel_A2.getCode());
			resp.setDesc(KYCEnum.KYCRiskLevel_A2.getDesc());
			resp.setLongDesc(KYCEnum.KYCRiskLevel_A2.getLongDesc());
		} else if (20 <= riskScore && riskScore <= 29) {
			resp.setRiskLevel(KYCEnum.KYCRiskLevel_A3.getCode());
			resp.setDesc(KYCEnum.KYCRiskLevel_A3.getDesc());
			resp.setLongDesc(KYCEnum.KYCRiskLevel_A3.getLongDesc());
		} else if (30 <= riskScore && riskScore <= 39) {
			resp.setRiskLevel(KYCEnum.KYCRiskLevel_A4.getCode());
			resp.setDesc(KYCEnum.KYCRiskLevel_A4.getDesc());
			resp.setLongDesc(KYCEnum.KYCRiskLevel_A4.getLongDesc());
		} else if (40 <= riskScore && riskScore <= 50) {
			resp.setRiskLevel(KYCEnum.KYCRiskLevel_A5.getCode());
			resp.setDesc(KYCEnum.KYCRiskLevel_A5.getDesc());
			resp.setLongDesc(KYCEnum.KYCRiskLevel_A5.getLongDesc());
		}

		logger.info("score = " + riskScore + "  scoreType = " + resp.getRiskLevel() + "   Kyc Desc = "
				+ resp.getDesc() + "  : " + resp.getLongDesc());

		// 保存用户信息到缓存中
		an.setScore(resp.getRiskLevel());
		an.setScoreDesc(resp.getDesc());
		an.setScoreLongDesc(resp.getLongDesc());

		// 保存用户信息到数据库中
		Answer oldAn = new Answer();
		oldAn = answerService.getByMobileId(an.getMobileId());

		// 如果系统中的用户存在
		SysUser user = sysUserService.getByMobileId(an.getMobileId());
		if ( user != null) {
			an.setUserId(user.getId());
			// 如果存在旧的数据，则直接修改
			if (oldAn != null) {
				Long oldAnId = oldAn.getId();
				ReqToModelHelper.copyReqValueToModel(an, oldAn);
				oldAn.setId(oldAnId);
				answerService.update(oldAn);
			} else {
				answerService.add(an);
			}
			// 删除缓存中的数据
			RedisCilent.delKey(CacheConstants.MobileId + an.getMobileId());
		}else{
			// 保存用户答题记录到缓存中
			RedisCilent.setString(CacheConstants.MobileId + an.getMobileId(),
					JsonUtils.toJson(an), TIME_OUT_SECONDS);
		}
		return resp;
	}

	private Integer getQuestionValue(String questionId, String selection) {
		Integer returnVal = 0;

		Long id = Long.valueOf(questionId);
		Question qu = questionService.findById(id);
		if (qu != null) {

			// 获取分值
			String[] valArray = null;
			String valStr = qu.getValue();
			valArray = valStr.split(",");

			// 用户选择项
			Integer sel = Integer.valueOf(selection);
			if (sel < valArray.length + 1) {
				returnVal = Integer.valueOf(valArray[sel - 1]);
			}
		}

		logger.info("questionId = " + questionId + "answerid = " + selection
				+ " returnVal = " + returnVal);

		return returnVal;
	}
	
	

}
